package com.ms.service.sheeter;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;

import com.ms.game.common.GameOptionInfo;
import com.ms.game.common.container.BasicSettingServerBinUtil;
import com.ms.game.slot.base.SlotBetInfo;
import com.ms.player.Player;
import com.xpec.c4.db.model.basic.SlotBasicGameModel;
import com.xpec.c4.db.model.basic.SlotJPBasicModel;
import com.xpec.c4.game.datamanager.agent.money.CoinType;


/**
 * 試算機基底類別
 * @author TW15012
 *
 */
public class BaseSheeter 
{

	/**一般玩家(正式幣，大於菜鳥等級)*/
	private static final String RAGULAR_PLAYER = "RAGULAR";
	/**菜鳥玩家(正式幣，小於菜鳥等級)*/
	private static final String ROOKIE_PLAYER = "ROOKIE";
	/**體驗玩家(體驗幣，0級)*/
	private static final String TRIAL_PLAYER = "TRIAL";
	
	/** 檢查JP */
	public static final int CHECK_JP = 1;
	/** 檢查吐水 */
	public static final int CHECK_WATER = 2;
	
	private NavigableMap<Integer, String> playerTypeMap;
	private int playerTypeCycle = 0;
	private int rookieLevel = 0;
	
	@SuppressWarnings("rawtypes")
	private Collection listeners; // 事件管理器
	
	public BaseSheeter()
	{
		listeners = new HashSet();
	}

	/**
	 * 設定角色循環<br>
	 * 例: RAGULAR:100,ROOKIE:10,TRIAL:50
	 */
	protected void setPlayerTypeCycle(String cycle){
		
		rookieLevel = BasicSettingServerBinUtil.getRookieLV();
		
		
		playerTypeMap = new TreeMap<Integer, String>();
		
		//解析cycle
		try {
			
			String[] playerCycles = cycle.split(",");
			for(String playerCycle : playerCycles){
				String[] set = playerCycle.split(":");
				String type = set[0];
				if(!type.equals(RAGULAR_PLAYER) && !type.equals(ROOKIE_PLAYER) && !type.equals(TRIAL_PLAYER)){
					continue;
				}
				
				int cycleCount = Integer.valueOf(set[1]);
				
				//只放進次數大於0的
				if(cycleCount > 0){
					playerTypeMap.put(playerTypeCycle, type);
					playerTypeCycle += cycleCount;	
				}
					
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 切換玩家類型(使用幣別、等級)
	 */
	protected void checkAndChangePlayerType(SlotBetInfo betInfo, int currentRound){
		
		if(playerTypeCycle <= 0){
			//如果都沒設定就不用切
			return;
		}

		
		Player player = betInfo.player;
		
		int entryKey = currentRound % playerTypeCycle;
		Entry<Integer, String> entry = playerTypeMap.floorEntry(entryKey);
		String playerType = entry.getValue();
		CoinType useCoinType = null;

		switch (playerType) {
		case RAGULAR_PLAYER:{
			player.setLevel(rookieLevel + 1);
			player.setTrialAccount(false);
			useCoinType = CoinType.GOLD;
			break;
		}
		case ROOKIE_PLAYER:{
			int level = rookieLevel - 1;
			if(level < 1){
				level = 1;
			}
			player.setLevel(level);
			player.setTrialAccount(false);
			useCoinType = CoinType.GOLD;
			break;
		}
		case TRIAL_PLAYER:{
			player.setLevel(0);
			player.setTrialAccount(true);
			useCoinType = CoinType.TRIAL;
			break;
		}

		default:
			break;
		}
		
		player.setCoin(useCoinType, new BigDecimal(100000000));
		betInfo.cointype = useCoinType;
		
	}

	/**
	 * 檢查剩餘的錢夠不夠
	 * @param checkType
	 * @param restMoney
	 * @return
	 */
	public String checkRestMoney
	(
			String gameType,
			SlotBasicGameModel gameModel,
			SlotJPBasicModel jpModel
	)
	{
		String hallType = gameModel.getHalltype();
		
		StringBuilder sBuilder = new StringBuilder();
		
		// 檢查吐水超過(水超過的值應該會是負值)
		int overMoney = GameOptionInfo.getPourOverMoney(gameType, hallType);
		int restMoney = gameModel.getPourTotal().intValue();
		if((restMoney * -1) > overMoney){
			sBuilder.append("水庫剩餘金錢不足,");	
		}
		
		// 檢查菜鳥吐水超過(水超過的值應該會是負值)
		int rookieOverMoney = GameOptionInfo.getRookiePourOverMoney(gameType, hallType); 
		int rookieRestMoney = gameModel.getRookie_pourTotal().intValue();
		if((rookieRestMoney * -1) > rookieOverMoney){
			sBuilder.append("菜鳥水庫剩餘金錢不足,");	
		}
		
		// 檢查體驗吐水超過(水超過的值應該會是負值)
		int trialOverMoney = GameOptionInfo.getPourOverMoney(gameType, hallType);
		int trialRestMoney = gameModel.getTrialpourTotal().intValue();
		if((trialRestMoney * -1) > trialOverMoney){
			sBuilder.append("體驗水庫剩餘金錢不足,");
		}
		
		// 檢查JP錢夠不夠
		if(jpModel.getJpvalue1().intValue() < 0){
			sBuilder.append("JP金額不足,");
		}
		if(jpModel.getHjp().intValue() < 0){
			sBuilder.append("HJP金額不足,");
		}
				
		return sBuilder.toString();
	}
	
	/**
	 * 執行試算機，所有試算機Override此方法
	 * @param runIDX 目前執行的是第幾批次
	 * @param loop 該批次應執行的次數
	 * @param betcount 下注數
	 * @param exportsize 該批次執行次數達到時輸出excel(因應遊戲得分結構大小去調整，結構太龐大的可能會因為RAM不夠而產生例外)
	 * @param runType 執行所需的參數
	 * @param cycle 切換使用角色資訊
	 */
	public void exec(int runIDX, int loop, int betcount, int exportsize, String runType, String cycle) {

	}
	
	
	@SuppressWarnings("unchecked")
	public void addEventListener(IBaseSheeterListener listener) {
		listeners.add(listener);
	}

	public void removeEventListener(IBaseSheeterListener listener) 
	{
		if (listeners == null)
			return;
		listeners.remove(listener);
	}

	@SuppressWarnings("rawtypes")
	public void nodifyListeners(BaseSheeterEvent event) 
	{
		if(listeners.size()==0)
		{
			return;
		}
		
		Iterator iter = (Iterator) listeners.iterator();
		while (iter.hasNext()) 
		{
			IBaseSheeterListener listener = (IBaseSheeterListener) iter.next();
			listener.doDispatchEvent(event);
		}
	}
}
